home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 by Christopher A. Wichura.
- See file GIFMachine.doc for full description of rights.
- */
-
- #include <exec/types.h>
- #include <exec/lists.h>
- #include <exec/nodes.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <graphics/rastport.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gfx.h>
- #include <intuition/intuition.h>
-
- extern void ReadCodex(void);
- extern void getgif(void);
-
- /* Nur fuer shoot */
- #include "shoot.h"
- extern int numtiles;
- extern UBYTE tiles[ TILESMAX ][ DEPTH ][ TILESHEIGHT ][ TILESWIDTH ];
-
- void beak( char * );
-
- int images;
- USHORT picinfowidth;
- USHORT picinfoheight;
- UBYTE ByteBuf;
- USHORT pimx, pimy;
- APTR pimdata;
- USHORT pimstart, pimlines;
- USHORT hires;
-
- struct MyMem {
- struct MinNode mm_Node;
- ULONG mm_Size;
- };
-
- /* some structures to make parsing the gif files a bit easier */
- struct GIFdescriptor {
- UWORD gd_Width;
- UWORD gd_Height;
- UBYTE gd_ColInfo;
- UBYTE gd_BackGround;
- UBYTE gd_PixelAspect; /* Aspect Ratio = (Pixel Aspect + 15) / 64 */
- };
-
- struct ImageDesc {
- UWORD id_Left;
- UWORD id_Top;
- UWORD id_Width;
- UWORD id_Height;
- UBYTE id_Info;
- };
-
- struct RGB {
- UBYTE rgb_Red;
- UBYTE rgb_Green;
- UBYTE rgb_Blue;
- };
-
- #define GIF_IMAGE 0x2C
- #define GIF_EXTENSION 0x21
- #define GIF_TERMINATOR 0x3B
-
- #define GIF_COMMENT_EXT 0xFE
-
- #define MAXCOLOURS 4096
-
- /* these next macros are used to get the r, g, and b values of a given
- index */
- #define GetRed(a) (UBYTE)(a >> 8)
- #define GetGreen(a) (UBYTE)((a >> 4) & 0xF)
- #define GetBlue(a) (UBYTE)(a & 0xF)
-
- /* whenever we want to abort we will return this as our error code */
- #define ABORTEXITVAL 1
-
- /* this struct is used to hold the linked list of comments found in the GIF
- file so that each can be written as a seperate ANNO chunk. */
- struct CommentNode {
- struct MinNode cn_Node;
- char *cn_Comment;
- ULONG cn_CommentLength;
- };
-
- /* function prototypes we use */
- void WarnMustUseCLI(void);
- void DoPattern(char *);
- void Convert(UWORD, UWORD, char *);
- BOOL IsDir(char *);
- void FlipWord(UWORD *);
- BOOL DoImage(APTR);
- BOOL DoExtension(APTR);
- BOOL WriteIFF(char *, BOOL);
- void PutValue(UWORD, UWORD, UWORD);
- UWORD GetValue(UWORD, UWORD);
- int ReadCode(APTR);
- void AddPixel(UBYTE);
- void StripBorder(void);
- BOOL BorderCheck(UWORD, UWORD);
- void DoXComp(void);
- void GIFtoSHAM(void);
- void InitDiff(void);
- ULONG RGBdiff(UBYTE, UBYTE, UBYTE, UBYTE, UBYTE, UBYTE);
- void OutDump(int);
- void OutRun(int, int);
- void InitMemory(void);
- char * MyAlloc(ULONG);
- void MyFree(char *);
- void FreeAll(UWORD);
- void MyExit(ULONG);
- void DoXFlip(void);
- void DoYFlip(void);
- void ReduceTo12(void);
- void DitherTo12(void);
- UWORD AddColour(struct RGB *);
-
- /* modules that want to use the Get/PutValue macros should include this
- next macro to externally reference the picture storage array */
- #define EXTERNBITPLANE extern struct RGB **BitPlane
-
- /* for use once colour palette has been reduced to 12 bits */
- #define GetValue(a, b) *((UWORD *)&BitPlane[b][a])
- #define PutValue(a, b, c) *((UWORD *)&BitPlane[b][a]) = c
-
- /* Copyright 1990 by Christopher A. Wichura.
- See file GIFMachine.doc for full description of rights.
- */
-
- #include <workbench/startup.h>
-
- struct GIFdescriptor gdesc;
-
- struct RGB **BitPlane;
- struct RGB GlobalColourTable[256];
-
- ULONG ImageNumber;
-
- /* the current GIF file handle */
- struct FileHandle *GIFfh = NULL;
-
- /* here we have some defines relating to our GADS call */
- #define ESC "\x9B"
- #define GIFMACH ESC "33;42mGIFMachine" ESC "32;40m"
-
- #define ARG_TEMPLATE "GIFfiles/M/A,TO/K,ALL/S,NOBORDER/K/N,XCOMP/S,DITHER/S,XFLIP/s,YFLIP/s,DEEP/S,BUFSIZE/K/N"
- #define ARG_FILES 0
- #define ARG_TO 1
- #define ARG_ALL 2
- #define ARG_NOBORD 3
- #define ARG_XCOMP 4
- #define ARG_DITHER 5
- #define ARG_FLIPX 6
- #define ARG_FLIPY 7
- #define ARG_DEEP 8
- #define ARG_BUFSIZ 9
- #define ARG_sizeof 10
-
- /* we will make the argument array global so that other modules can get at
- the ARG_TO, ARG_ALL and ARG_XCOMP fields easily */
- struct RDArgs *ArgsPtr;
- char *ArgArray[ARG_sizeof];
- BOOL ArgToIsDir;
-
- /* size of the read buffered i/o space */
- static ULONG BufSize = 2048; /* default size is 2k */
-
- int NoBorderLineThresh = 0;
-
- /* some mem pointers used when we do dithering */
- BYTE *CurrentLineErr[3];
- BYTE *LastLineErr[3];
-
- /* this flag says if we scaled the image */
- BOOL DidXComp;
-
- /* we print this when the user hits the break key */
- char *AbortMsg = "*** User Interruption!\n";
-
- void MyExit( result)
- ULONG result;
- {
- if (GIFfh)
- Close(GIFfh);
-
- FreeAll( (UWORD) 1 );
- FreeAll( (UWORD) 0 );
-
- return(result);
- }
-
-
- APTR DosBase;
- FILE *out;
-
- void main( argc, argv )
- int argc;
- char *argv[];
- {
- DosBase = (APTR) OpenLibrary( "dos.library", 0 );
-
- if (DosBase)
- {
- {
- int f;
- printf("%s %s to %s\n", argv[0], argv[1], argv[2] );
-
- out = fopen( argv[2], "w" );
- beak( argv[1] );
-
- fclose( out );
- }
- CloseLibrary( DosBase );
- }
- else
- {
- printf("Could not open dos.library\n");
- }
- }
-
- /* here we have the routine that gets ready to do the conversion */
-
- void beak( name )
- char *name;
- {
- register int index;
- /*char *basename;
- char *ptr;*/
- char sig[7];
- int size;
- int error;
- int colours;
- LONG cmdcode;
- unsigned char rid;
-
- printf("name: %s\n", name );
-
- if (!(GIFfh = (struct FileHandle *) Open(name, MODE_OLDFILE))) {
- printf("Error #%ld trying to open %s...\n", IoErr(), name);
- goto LeaveConvert;
- }
-
- sig[6] = NULL;
-
- if ((Read(GIFfh, sig, 6) != 6) || strncmp("GIF", sig, 3)) {
- printf("%s is not a GIF file...\n", name);
- printf("%s\n", sig );
- goto LeaveConvert;
- }
-
- if (Read(GIFfh, (char *)&gdesc, 7) != 7) {
- printf("Error reading screen descriptor.\n");
- goto LeaveConvert;
- }
-
- FlipWord(&gdesc.gd_Width);
- FlipWord(&gdesc.gd_Height);
-
- printf("Signature = \"%s\", Width = %ld, Height = %ld\n",
- sig, gdesc.gd_Width, gdesc.gd_Height);
-
- DidXComp = 0;
- colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
-
- if (!(gdesc.gd_ColInfo & 1L << 7)) {
- printf("No global colour map supplied, using internal.\n");
-
- for (index = 0; index < colours; index++) {
- GlobalColourTable[index].rgb_Red =
- GlobalColourTable[index].rgb_Green =
- GlobalColourTable[index].rgb_Blue = index;
- }
- } else {
- printf("Global colour map contains %ld entries.\n", colours);
-
- for (index = 0; index < colours; index++) {
- if (Read(GIFfh, &GlobalColourTable[index], 3) != 3) {
- printf("Error reading global colour #%ld.\n",
- index);
- goto LeaveConvert;
- }
- }
- }
-
- size = ((gdesc.gd_Width + 7) / 8) + 1;
- size += (size + 127) >> 7;
-
- size = (gdesc.gd_Width + 1) * sizeof(struct RGB);
-
-
- ImageNumber = 1;
-
- /* at this point we start looking for images, extensions or the gif
- terminator. we call the appropriate routine as we find each. */
-
- for (error = FALSE; error == FALSE;) {
- if ( Read( GIFfh, &rid, 1) == -1) {
- printf("...I/O error reading GIF file.\n");
- goto LeaveConvert;
- }
- cmdcode=rid;
-
- switch(cmdcode) {
- case GIF_IMAGE:
- error = DoImage( (APTR) GIFfh);
- break;
-
- case GIF_EXTENSION:
- error = DoExtension( (APTR) GIFfh);
- break;
-
- case GIF_TERMINATOR:
- break;
-
- default:
- printf("...Unknown directive #%ld encountered.\n",
- cmdcode);
- error = TRUE;
- }
- }
-
- LeaveConvert:
- if (GIFfh) {
- Close(GIFfh);
- GIFfh = NULL;
- }
- }
-
- struct MinList Mem[2];
- UWORD CurrentMem;
-
- char *MyAlloc(size)
- ULONG size;
- {
- register struct MyMem *theMemory;
- register ULONG newsize;
-
- newsize = size + sizeof(struct MyMem);
-
- if (!(theMemory = (struct MyMem *)AllocMem(newsize, MEMF_PUBLIC|MEMF_CLEAR)))
- return NULL;
-
- AddTail((struct List *)&Mem[CurrentMem], (struct Node *)&theMemory->mm_Node);
- theMemory->mm_Size = newsize;
-
- return (char *)theMemory + sizeof(struct MyMem);
- }
-
- void MyFree(MemPtr)
- char *MemPtr;
- {
- register struct MyMem *theMemory;
-
- theMemory = (struct MyMem *)(MemPtr - sizeof(struct MyMem));
-
- Remove((struct Node *)&theMemory->mm_Node);
- FreeMem((char *)theMemory, theMemory->mm_Size);
- }
-
- void FreeAll(memlist)
- UWORD memlist;
- {
- register struct MyMem *theMemory;
-
- while (theMemory = (struct MyMem *)RemTail((struct List *)&Mem[memlist]))
- FreeMem((char *)theMemory, theMemory->mm_Size);
- }
-
- struct MinList CommentList;
- static UBYTE buf[256];
-
- BOOL DoExtension(fh)
- APTR fh;
- {
- register LONG size;
- register LONG cmdcode;
- register char *Comment;
- register char *OldComment;
- register int CommentLength;
- register int OldCommentLength;
- register struct CommentNode *cn;
- unsigned char rid;
-
- if (Read( fh, &rid, 1) == -1) {
- printf("...I/O error reading extension block function code\n");
- return TRUE;
- }
- cmdcode=rid;
-
- switch(cmdcode) {
- case GIF_COMMENT_EXT:
- printf("...Comment extension encountered. Contents will be stored in an ANNO chunk.\n");
-
- if (!(cn = (struct CommentNode *)MyAlloc(sizeof(struct CommentNode)))) {
- printf("......Out of memory allocating comment block.\n");
- return TRUE;
- }
-
- Comment = NULL;
- CommentLength = 0;
-
- for (;;) {
- if ((size = fgetc(fh)) == -1) {
- printf("......I/O Error reading comment block.\n");
- return TRUE;
- }
-
- if (size) {
- if (fread(fh, buf, 1, size) != size) {
- printf("......I/O Error reading comment block.\n");
- return TRUE;
- }
-
- OldComment = Comment;
- OldCommentLength = CommentLength;
- CommentLength += size;
-
- if (!(Comment = MyAlloc(CommentLength))) {
- printf("......Out of memory allocating comment block.\n");
- return TRUE;
- }
-
- if (OldCommentLength) {
- CopyMem(OldComment, Comment, OldCommentLength);
- MyFree(OldComment);
- }
-
- CopyMem(buf, &Comment[OldCommentLength], size);
- } else { /* end of comment so store it */
- cn->cn_Comment = Comment;
- cn->cn_CommentLength = CommentLength;
- AddTail((struct List *)&CommentList, (struct Node *)cn);
- return FALSE;
- }
- }
- break;
-
- default:
- printf("...Extension block function code #%ld not know, skipping.\n",
- cmdcode);
-
- /* we must skip over any data for the extension block */
- for (;;) {
- if ((size = fgetc(fh)) == -1) {
- printf("...I/O Error skipping unknown extension block.\n");
- return TRUE;
- }
-
- if (size == 0)
- return FALSE;
-
- if (fread(fh, buf, 1, size) != size) {
- printf("...I/O Error skipping unknown extension block.\n");
- return TRUE;
- }
- }
- break;
- }
- }
-
- /* this will convert a word from LSB/MSB to MSB/LSB */
- void FlipWord(word)
- UWORD *word;
- {
- register UBYTE swap1;
- register UBYTE swap2;
-
- swap1 = *word & 0xFF;
- swap2 = (*word & 0xFF00) >> 8;
- *word = swap1 << 8 | swap2;
- }
-
- /*struct GIFdescriptor gdesc;*/
-
- static struct ImageDesc idesc;
- /*struct RGB GlobalColourTable[256];*/
- static struct RGB LocalColourTable[256];
- /*ULONG ImageNumber;*/
-
- extern char *AbortMsg;
-
- static UWORD Xpos, Ypos;
- static BOOL interleave;
-
- static UBYTE LeaveStep[5] = {1, 8, 8, 4, 2};
- static UBYTE LeaveFirst[5] = {0, 0, 4, 2, 1};
-
- /* some variables used by the decompressor */
- UWORD ReadError;
- UBYTE CodeSize;
- UWORD EOFCode;
- UBYTE ReadMask;
- UWORD CompDataPointer;
- UWORD CompDataCount;
- UBYTE CompData[256];
-
- /* tables used by the decompressor */
- static UWORD Prefix[4096];
- static UBYTE Suffix[4096];
- static UBYTE OutCode[1025];
-
- APTR dagiffh;
- UWORD Code;
- APTR date;
-
- BOOL DoImage(fh)
- APTR fh;
- {
- register int index;
- register int colours;
-
- date= (APTR) &CompData[0];
- dagiffh=fh;
-
- printf("...Image #%ld encountered.\n", ImageNumber++);
-
- if (Read(fh, (char *)&idesc, 9) != 9) {
- printf("......Error reading image descriptor.\n");
- return TRUE;
- }
-
- FlipWord(&idesc.id_Left);
- FlipWord(&idesc.id_Top);
- FlipWord(&idesc.id_Width);
- FlipWord(&idesc.id_Height);
-
- interleave = idesc.id_Info & 1L << 6;
- if (interleave)
- interleave = 1;
-
- printf("......Xpos from %ld to %ld, Ypos from %ld to %ld, %sinterlaced.\n",
- idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
- idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
- interleave ? "" : "not ");
-
- if (idesc.id_Info & 1L << 7) {
- colours = 1L << ((idesc.id_Info & 7) + 1);
- printf("......Local colour map contains %ld entries.\n", colours);
-
- for (index = 0; index < colours; index++) {
- if (Read(fh, &LocalColourTable[index], 3) != 3) {
- printf("......Error reading local colour #%ld.\n",
- index);
- return TRUE;
- }
- }
- } else {
- colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
- CopyMem((char *)GlobalColourTable, (char *)LocalColourTable,
- sizeof(LocalColourTable));
- }
-
- Xpos = Ypos = 0;
-
- /* now we are ready to read the image in so do it! */
-
- {
- int MaxCode, ClearCode, CurCode,
- OldCode, InCode, FreeCode;
- int OutCount;
- int FirstFree;
- UBYTE InitCodeSize, FinChar, BitMask;
-
- printf("......Decompressing line number %5ld", Ypos);
-
- /* get the codesize and do general setup for decompression */
- if (Read(fh, &CodeSize, 1) == -1) {
- printf("\n......I/O Error during decompression.\n");
- return TRUE;
- }
-
- ClearCode = 1L << CodeSize;
- EOFCode = ClearCode + 1;
- FreeCode = FirstFree = ClearCode + 2;
-
- CodeSize++; /* per GIF spec */
- InitCodeSize = CodeSize;
- MaxCode = 1L << CodeSize;
- ReadError = ReadMask = OutCount = 0;
- CompDataPointer = CompDataCount = 0;
-
- BitMask = colours - 1;
-
- Code = ReadCode(fh);
- /* ReadCodex();*/
- while( Code != EOFCode ) {
- if (ReadError)
- return TRUE;
-
- if (Code == ClearCode) {
- CodeSize = InitCodeSize;
- MaxCode = 1L << CodeSize;
- FreeCode = FirstFree;
- FinChar = CurCode = OldCode = Code = ReadCode(fh);
- /* ReadCodex();*/
- FinChar = CurCode = OldCode = Code;
- AddPixel(FinChar);
- } else {
- CurCode = InCode = Code;
-
- if (CurCode >= FreeCode) {
- CurCode = OldCode;
- OutCode[OutCount++] = FinChar;
- }
-
- while (CurCode > BitMask) {
- if (OutCount > 1024) {
- printf("\n......Corrupt GIF file (OutCount)\n");
- return TRUE;
- }
-
- OutCode[OutCount++] = Suffix[CurCode];
- CurCode = Prefix[CurCode];
- }
-
- FinChar = CurCode;
- AddPixel(FinChar);
-
- for (index = OutCount - 1; index >= 0; index--)
- AddPixel(OutCode[index]);
- OutCount = 0;
-
- Prefix[FreeCode] = OldCode;
- Suffix[FreeCode] = FinChar;
- OldCode = InCode;
-
- if (++FreeCode >= MaxCode) {
- if (CodeSize < 12) {
- CodeSize++;
- MaxCode <<= 1;
- }
- }
- }
-
- Code = ReadCode(fh);
- /* ReadCodex();*/
- }
- }
-
- if ((Code = fgetc(fh)) == -1)
- return TRUE;
-
- /* done decompressing. Erase decompressing message and exit */
- printf("\x9B22D\x9BKed.\n");
-
- if (Code != 0) {
- printf("......Warning: Unaligned packet.\n");
- ungetc(fh, Code);
- }
-
- return FALSE;
- }
-
- int ReadCode(fh)
- APTR fh;
- {
- register int temp;
- register int DstMasked;
- register int DstMask;
- register LONG size;
- unsigned char rid;
-
- temp = 0;
- DstMasked = 1L << CodeSize;
- for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
- if (!ReadMask) {
- if (CompDataPointer == CompDataCount) {
- if (Read( fh, &rid, 1) == -1) {
- printf("\n......I/O Error during decompression.\n");
- ReadError = 1;
- return EOFCode;
- }
- size=rid;
-
- if (Read(fh, (char *)CompData, size) != size) {
- printf("\n......I/O Error during decompression.\n");
- ReadError = 1;
- return EOFCode;
- }
-
- CompDataCount = size;
- CompDataPointer = 0;
- }
-
- ReadMask = 1;
- ByteBuf = CompData[CompDataPointer++];
- }
-
- if (ByteBuf & ReadMask)
- temp |= DstMask;
-
- ReadMask <<= 1;
- }
-
- return temp;
- }
-
- void AddPixel(index)
- UBYTE index;
- {
- register UWORD tile;
- UWORD row;
- UWORD byte;
-
- register UWORD manip2;
- register UWORD manip;
- register UBYTE schreib;
-
- /* SetAPen( rastport, index );*/
- /* WritePixel( rastport, XStore, YStore+20 );*/
-
- fprintf( out, "%c", index );
-
- /* tile = (Ypos/16)*20 + Xpos/16;
-
- row = Ypos & 15;
- byte = (Xpos & 8)/8;
-
- {
- manip = 1 << ( 7 - ( Xpos & 7 ) );
- manip2 = 255 ^ manip;
-
- if( ( index & 1 ) != 0 )
- {
- tiles[ tile ][ 0 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 0 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 2 ) != 0 )
- {
- tiles[ tile ][ 1 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 1 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 4 ) != 0 )
- {
- tiles[ tile ][ 2 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 2 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 8 ) != 0 )
- {
- tiles[ tile ][ 3 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 3 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 16 ) != 0 )
- {
- tiles[ tile ][ 4 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 4 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 32 ) != 0 )
- {
- tiles[ tile ][ 5 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 5 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 64 ) != 0 )
- {
- tiles[ tile ][ 6 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 6 ][ row ][ byte ] &= manip2;
- }
-
- if( ( index & 128 ) != 0 )
- {
- tiles[ tile ][ 7 ][ row ][ byte ] |= manip;
- }
- else
- {
- tiles[ tile ][ 7 ][ row ][ byte ] &= manip2;
- }
-
- }
- */
- if (++Xpos == idesc.id_Width) {
- Xpos = 0;
- Ypos += LeaveStep[interleave];
- if (Ypos >= idesc.id_Height)
- Ypos = LeaveFirst[++interleave];
-
- printf("\x9B5D%5ld", Ypos + idesc.id_Top);
- }
- }
-